package com.kf.config;

import com.aliyun.oss.*;
import com.aliyun.oss.model.*;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.UUID;

/**
 *
 *
 * @author Honey
 * @descibe oss
 * @date 2022/12/19
 */
@Component
public class AliyunOSSUtil {


    public static final String DOCX="docx";
    public static final String TXT="txt";
    public static final String PDF="pdf";
    public static final String DOC="doc";
    public static final String XLS="xls";
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AliyunOSSUtil.class);
    /**
     * bucket名称
     */
    ResourceBundle resource = ResourceBundle.getBundle("oss");
    String endpoint= "https://oss-cn-heyuan.aliyuncs.com";
    String accessKeyId= "LTAI5tGvZU3ctu3jBwuZRAys";
    String    accessKeySecret= "K3jNDQfcgRnQm5R6z1jkTl14gWOFRh";
    String  bucketName= "graduate-system";

    public String getFileCode(){
        String uuid = UUID.randomUUID().toString();
        long timeMillis = System.currentTimeMillis();
        return uuid+timeMillis;
    }

    /**
     * 上传文件
     */
    public String upLoad(File file,String url) {


        // 判断文件
        if (file == null) {
            return null;
        }
//
//
//        String bucketName = resource.getString("bucketName");
//        String fileHost = resource.getString("fileHost");

        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret );


        System.out.println(client);
        try {
            // 判断容器是否存在,不存在就创建
            if (!client.doesBucketExist(bucketName)) {
                client.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                client.createBucket(createBucketRequest);
            }
            // 设置文件路径和名称
            String fileUrl = url + "/" + file.getName();

            // 上传文件
            PutObjectResult result = client.putObject(new PutObjectRequest(bucketName, fileUrl, file));
            // 设置权限(公开读)
            client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            if (result != null) {
                LOGGER.info("------OSS文件上传成功------" + "https://makeromance.oss-cn-hangzhou.aliyuncs.com/" + fileUrl);
            }

            file.delete();
        } catch (OSSException oe) {
            LOGGER.error(oe.getMessage());
        } catch (ClientException ce) {
            LOGGER.error(ce.getErrorMessage());
        } finally {
            if (client != null) {
                client.shutdown();
            }
        }
        return null;
    }

    public String upLoad1(File file,String url){
        String name=file.getName();
        System.out.println(name);
        String objectName = url+"/"+name;

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret );
//        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            // 创建InitiateMultipartUploadRequest对象。
            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
            // 初始化分片。
            InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
            // 返回uploadId，它是分片上传事件的唯一标识。您可以根据该uploadId发起相关的操作，例如取消分片上传、查询分片上传等。
            String uploadId = upresult.getUploadId();

            // partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
            List<PartETag> partETags =  new ArrayList<>();
            // 每个分片的大小，用于计算文件有多少个分片。单位为字节。
            //1 MB。
            final long partSize = 1024 * 1024L;

            System.out.println(file.getAbsolutePath());
            long fileLength = file.length();
            int partCount = (int) (fileLength / partSize);
            if (fileLength % partSize != 0) {
                partCount++;
            }
            // 遍历分片上传。
            for (int i = 0; i < partCount; i++) {
                long startPos = i * partSize;
                long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
                InputStream instream = new FileInputStream(file);
                // 跳过已经上传的分片。
                instream.skip(startPos);
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setInputStream(instream);
                // 设置分片大小。除了最后一个分片没有大小限制，其他的分片最小为100 KB。
                uploadPartRequest.setPartSize(curPartSize);
                // 设置分片号。每一个上传的分片都有一个分片号，取值范围是1~10000，如果超出此范围，OSS将返回InvalidArgument错误码。
                uploadPartRequest.setPartNumber( i + 1);
                // 每个分片不需要按顺序上传，甚至可以在不同客户端上传，OSS会按照分片号排序组成完整的文件。
                UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
                // 每次上传分片之后，OSS的返回结果包含PartETag。PartETag将被保存在partETags中。
                partETags.add(uploadPartResult.getPartETag());
            }


            // 创建CompleteMultipartUploadRequest对象。
            // 在执行完成分片上传操作时，需要提供所有有效的partETags。OSS收到提交的partETags后，会逐一验证每个分片的有效性。当所有的数据分片验证通过后，OSS将把这些分片组合成一个完整的文件。
            CompleteMultipartUploadRequest completeMultipartUploadRequest =
                    new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

            CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
            System.out.println(completeMultipartUploadResult.getETag());

            file.delete();
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    return null;
    }


    public void exportOssFile(OutputStream os, String objectName) throws IOException {

        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);

        // 读取文件内容。
        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
        BufferedOutputStream out = new BufferedOutputStream(os);
        byte[] buffer = new byte[1024];
        int lenght = 0;
        while ((lenght = in.read(buffer)) != -1) {
            out.write(buffer, 0, lenght);
        }

        out.flush();
        out.close();
        in.close();

    }

    public  boolean deleteFile(String filePath) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        boolean exist = ossClient.doesObjectExist(bucketName, filePath);
        if (!exist) {
            LOGGER.error("文件不存在,filePath={}", filePath);
            return false;
        }
        LOGGER.info("删除文件,filePath={}", filePath);
        ossClient.deleteObject(bucketName, filePath);
        ossClient.shutdown();
        return true;
}

    public String upLoad3(MultipartFile file, String url,String fileCode,String suffix) {


        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret );


        System.out.println(client);
        try {
            // 判断容器是否存在,不存在就创建
            if (!client.doesBucketExist(bucketName)) {
                client.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                client.createBucket(createBucketRequest);
            }
            // 设置文件路径和名称
            String fileUrl = url + "/" + fileCode+"."+suffix;
            System.out.println("fileurl:"+fileUrl);
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileUrl, inputStream);
            // 设置该属性可以返回response。如果不设置，则返回的response为空。
            putObjectRequest.setProcess("true");
            // 创建PutObject请求。
            PutObjectResult result = client.putObject(putObjectRequest);
            // 如果上传成功，则返回200。
            System.out.println(result.getResponse().getStatusCode());
            // 设置权限(公开读)
            client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            if (result != null) {
                LOGGER.info("------OSS文件上传成功------" + "https://makeromance.oss-cn-hangzhou.aliyuncs.com/" + fileUrl);
            }

//            file.delete();
        } catch (OSSException oe) {
            LOGGER.error(oe.getMessage());
        } catch (ClientException ce) {
            LOGGER.error(ce.getErrorMessage());
        } finally {
            if (client != null) {
                client.shutdown();
            }
        }
        return null;
    }

}





